import smtplib
import pandas as pd
import argparse
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

def send_email(smtp_server, smtp_port, sender_email, sender_password, 
               receiver_email, subject, body, attachments=None):
    """发送单封邮件"""
    try:
        # 创建邮件对象
        msg = MIMEMultipart()
        msg['From'] = sender_email
        msg['To'] = receiver_email
        msg['Subject'] = subject
        
        # 添加邮件正文
        msg.attach(MIMEText(body, 'html' if '<html>' in body else 'plain'))
        
        # 添加附件
        if attachments:
            for attachment_path in attachments:
                if os.path.exists(attachment_path):
                    with open(attachment_path, 'rb') as attachment:
                        part = MIMEBase('application', 'octet-stream')
                        part.set_payload(attachment.read())
                    
                    encoders.encode_base64(part)
                    filename = os.path.basename(attachment_path)
                    part.add_header(
                        'Content-Disposition',
                        f"attachment; filename= {filename}",
                    )
                    msg.attach(part)
        
        # 发送邮件
        with smtplib.SMTP(smtp_server, smtp_port) as server:
            server.starttls()  # 启用TLS加密
            server.login(sender_email, sender_password)
            server.sendmail(sender_email, receiver_email, msg.as_string())
        
        return True, f"邮件发送成功: {receiver_email}"
        
    except Exception as e:
        return False, f"邮件发送失败 {receiver_email}: {str(e)}"

def batch_send_emails(smtp_server, smtp_port, sender_email, sender_password, 
                     recipients_file, subject, body_file, attachments=None):
    """批量发送邮件"""
    try:
        # 读取收件人列表（支持Excel或CSV）
        ext = os.path.splitext(recipients_file)[1].lower()
        if ext in ['.xlsx', '.xls']:
            df = pd.read_excel(recipients_file)
        elif ext == '.csv':
            df = pd.read_csv(recipients_file)
        else:
            print("不支持的收件人文件格式，仅支持Excel和CSV")
            return
        
        # 检查是否包含必要的邮箱列
        email_columns = [col for col in df.columns if 'email' in col.lower()]
        if not email_columns:
            print("收件人文件中未找到包含'email'的列")
            return
        email_col = email_columns[0]
        
        # 读取邮件正文
        with open(body_file, 'r', encoding='utf-8') as f:
            body_template = f.read()
        
        # 批量发送
        success_count = 0
        total_count = len(df)
        
        print(f"开始发送邮件，共 {total_count} 个收件人")
        
        for _, row in df.iterrows():
            email = str(row[email_col]).strip()
            if not email or '@' not in email:
                print(f"跳过无效邮箱: {email}")
                continue
            
            # 替换正文中的变量（如{name}）
            body = body_template
            for col, value in row.items():
                body = body.replace(f"{{{col}}}", str(value))
            
            # 发送邮件
            success, message = send_email(
                smtp_server, smtp_port, sender_email, sender_password,
                email, subject, body, attachments
            )
            print(message)
            if success:
                success_count += 1
        
        print(f"\n发送完成！成功: {success_count}/{total_count}")
        
    except Exception as e:
        print(f"批量发送失败: {str(e)}")

if __name__ == "__main__":
    # 安装依赖提示
    try:
        import pandas
        import openpyxl
    except ImportError:
        print("请先安装依赖: pip install pandas openpyxl")
        exit(1)
    
    parser = argparse.ArgumentParser(description='批量发送邮件脚本')
    parser.add_argument('--smtp-server', required=True, help='SMTP服务器地址，如smtp.gmail.com')
    parser.add_argument('--smtp-port', type=int, default=587, help='SMTP端口，默认587')
    parser.add_argument('--sender', required=True, help='发件人邮箱')
    parser.add_argument('--password', required=True, help='发件人密码或授权码')
    parser.add_argument('--recipients', required=True, help='收件人列表文件（Excel或CSV）')
    parser.add_argument('--subject', required=True, help='邮件主题')
    parser.add_argument('--body', required=True, help='邮件正文模板文件（txt或html）')
    parser.add_argument('--attachments', help='附件路径，多个用逗号分隔')
    
    args = parser.parse_args()
    
    # 处理附件
    attachments = args.attachments.split(',') if args.attachments else None
    
    batch_send_emails(
        smtp_server=args.smtp_server,
        smtp_port=args.smtp_port,
        sender_email=args.sender,
        sender_password=args.password,
        recipients_file=args.recipients,
        subject=args.subject,
        body_file=args.body,
        attachments=attachments
    )
